Skip to content

reimplement: SHC_3BB0A8C1_0x00479C80 optimization issues#76

Draft
TheRedDaemon wants to merge 1 commit into
mainfrom
reimpl/SHC_3BB0A8C1_0x00479C80
Draft

reimplement: SHC_3BB0A8C1_0x00479C80 optimization issues#76
TheRedDaemon wants to merge 1 commit into
mainfrom
reimpl/SHC_3BB0A8C1_0x00479C80

Conversation

@TheRedDaemon
Copy link
Copy Markdown
Contributor

This one might need AI work. I was unable to produce the 100% match due to the way the second loop variable is computed:

0x479cb9 : jne -0x14
0x479cbb : -lea eax, [esi + 1]
           : +mov eax, 1        (findSamplePlaceForSoundUnk.cpp:27)
0x479cbe : pop esi
0x479cbf : -nop
0x479cc0 : cmp dword ptr [edx], 0       (findSamplePlaceForSoundUnk.cpp:28)

Common sense tells me both loops need to be forward. Apparently, the original did not allow the compiler to "know" the start value of the second loop and made it dependend on the internal run value of the first, or the compiler decided here to use lea instead of mov, while having to pad with a nop then.

The rest seems to fit. I created a temporary global in the cpp file to simulate the struct variable access. It uses one of these direct "add" that do not work for the resolver.

So, current state:

  • Issue with loop run values (maybe).
  • Struct Resolver shortcoming, therefore currently temporary for tests.

Would be cool if you could try this one also with the AI method, under the assumption it is not too confused by the resolver issue.

@TheRedDaemon TheRedDaemon requested a review from gynt May 17, 2026 21:47
@gynt
Copy link
Copy Markdown
Contributor

gynt commented May 22, 2026

I used up all my Claude tokens for today on this issue. Every change to the source code led to major differences. Basically, esi is assumed to be 0 by the msvc optimizer and uses this to its advantage to produce a byte shorter (faster?) code. I tried combinations of optimize pragma's, including options "gy" produced the 91.53%.

Does the StructResolver shortcoming resolve itself (no pun intended) when DAT_SoundEffectsHelperData1 becomes reimplemented?

@TheRedDaemon
Copy link
Copy Markdown
Contributor Author

TheRedDaemon commented May 22, 2026

Ok, I guess then it does not make sense to use more tokens here unless you want to try one or two iterations on the raw Ghidra export, if you have not already done so. But this is up to you.
One fear I have is that it might actually be related to the position of the function in the original: That it just decided to use another opcode to the certain jumps aligned. But this still seems unlikely.

I actually had to notice something: The struct resolvers do not work together with reccmp. I was unable to properly annotate the static created by the template, even with tricks. Their repo reads like normal statics should work, but I have no idea how to implement a template static.

This might be something to ask them, I guess?

@gynt
Copy link
Copy Markdown
Contributor

gynt commented May 22, 2026

Yes! They have a Discord server too. disinvite is the most important developer I think currently.

Can you provide a code snippet of how you expected things to work?

@TheRedDaemon
Copy link
Copy Markdown
Contributor Author

TheRedDaemon commented May 22, 2026

I can provide a reduced version that I tried, which seems to not have worked.
I tried to use the "instance" Wrapper directly:

struct StructResolver {
    template <typename T, int gameAddress> struct Instance;
}

// Try 1
// GLOBAL: TARGET 0x00DF37F0
template <typename T> struct StructResolver::Instance<T, 0x00DF37F0> {
    // Try 2
    // GLOBAL: TARGET 0x00DF37F0
    static T instance;
};
// Try 3
// GLOBAL: TARGET 0x00DF37F0
template <typename T> T StructResolver::Instance<T, 0x00DF37F0>::instance;

// Try 4
// GLOBAL: TARGET 0x00DF37F0
StructResolver::Instance<ActualType, 0x00DF37F0> testInstance;

Non of this seems to work. (And it is a bit simpler as our actual resolver, which currently hiddes the instance and only exposes a ptr.)
I do not really think any of these truly express the template instance global. Even 4 would be wrong, since the static does not truly belong to the wrapping struct.

Which also means I actually do not really have an idea. Maybe you can attach it to the specific template instance somehow and just define it in relation to the template? No idea. But at least the reccmp output properly shows the instance, it can just not attach the annotation to it.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants